import _ from 'lodash';
import { message } from 'antd';
import { isSuccess } from '@/utils/request';
import modelType from '../constant/modelTypeConstant';
import ComputeOverviewTable from './ComputeOverviewTable';

const noop = () => {};
const { time = noop, timeLog = noop, timeEnd = noop } = console;

function* getState(select, namespace) {
    return yield select(state => state[namespace]);
}

function* searchPostData(select, namespace) {
    const currentState = yield* getState(select, namespace);

    const periodStr = currentState.period || '';
    const year = periodStr.substr(0, 4);
    const month = periodStr.substr(5);
    return {
        year,
        month: month ? String(parseInt(month, 10)) : month,
        actionType: currentState.actionType || 1,
        ...currentState.searchModel
    };
}

function* getTableData(select, namespace) {
    const currentState = yield* getState(select, namespace);
    return {
        dataSource: currentState.dataSource,
        footerSource: currentState.footerSource,
        historySource: currentState.historySource || []
    };
}

function delay (ms) {
    return new Promise(resolve => {
        setTimeout(resolve, ms);
    });
}

const shareNamespace = 'recheckSharedModel';
const overviewRecheckModel = (
    namespace,
    {
        latestSalaryYearMonth,
        getCheckButtons,
        queryTableBodyData,
        updateData,
        passCheck,
        finalPassCheck,
        rejectCheck,
        finalRejectCheck
    }
) => ({
    namespace,
    state: {
        period: null,
        checkButtonList: [],
        searchModel: {},
        tableLoading: false,
        stepLoading: false,
        rowKey: 'deptCode',
        dataSource: [],
        footerSource: null
    },
    reducers: {
        [modelType.SET_MULTI_STORE](state, action) {
            return {
                ...state,
                ...action.payload
            };
        },
        [modelType.SET_LOADING](state, action) {
            return {
                ...state,
                ...action.payload
            };
        },

        [modelType.INIT_STORE](state) {
            return {
                ...state,
                checkButtonList: [],
                period: null,
                dataSource: [],
                footerSource: null
            };
        },

        [modelType.RESET_STORE](state, action) {
            return {
                ...state,
                checkButtonList: [],
                searchModel: {
                    encryptTotalPayAmtLowest: '',
                    encryptTotalPayAmtHighest: '',
                    encryptTotalTaxAmtLowest: '',
                    encryptTotalTaxAmtHighest: '',
                    encryptAverageAmtLowest: '',
                    encryptAverageAmtHighest: '',
                    departmentCode: null,
                    organizationCode: null,
                    ...action.payload
                },
                period: null,
                dataSource: [],
                historySource: [],
                footerSource: null
            };
        },
        /**
         * 更变月份
         * @param action.payload 月份
         */
        [modelType.SET_PERIOD](state, action) {
            const { payload: period } = action;

            return {
                ...state,
                period
            };
        },
        [modelType.SET_PAGE_INFO](state, action) {
            const {
                overviewList: dataSource,
                overviewTotal: footerData,
                historySource
            } = action.payload.data;

            const footerSource = footerData || {};
            footerSource.deptName = '合计';

            return {
                ...state,
                dataSource,
                footerSource: [footerSource],
                historySource: historySource || dataSource
            };
        },
        [modelType.SET_SEARCH_CONDITION](state, action) {
            const { searchModel } = state;
            const { payload } = action;
            return {
                ...state,
                searchModel: {
                    ...searchModel,
                    ...payload
                }
            };
        }
    },
    effects: {
        *[modelType.E_INIT](state, { put, call, select, all }) {
            time('初始化%c%s');
            timeLog('初始化%c%s', 'color: #FAA809;', ' -> 开始初始化');
            timeLog('初始化%c%s', 'color: #FAA809;', ' -> 设置loading：true状态 -> 开始');
            // 如果不是切换月份，则调用接口获取默认年月
            yield put({
                type: modelType.SET_LOADING,
                payload: { tableLoading: true }
            });
            timeLog('初始化%c%s', 'color: #FAA809;', ' -> 设置loading: true状态 -> 完成');
            let postData = yield* searchPostData(select, namespace);
            if (!state.payload) {
                timeLog('初始化%c%s', 'color: #FAA809;', ' -> 获取最近薪资月份 -> 开始');
                const response = yield call(latestSalaryYearMonth, {
                    organizationCode: postData.organizationCode
                });
                timeLog('初始化%c%s', 'color: #FAA809;', ' -> 获取最近资月份 -> 结束');

                if (!isSuccess(response)) {
                    timeLog('初始化%c%s', 'color: #FAA809;', ' -> 请求最近薪资月份失败');
                    message.error(`${response.msg}`);
                    timeLog('初始化%c%s', 'color: #FAA809;', ' -> 设置loading：false状态 -> 开始');
                    yield put({
                        type: modelType.SET_LOADING,
                        payload: { tableLoading: false }
                    });
                    timeLog('初始化%c%s', 'color: #FAA809;', ' -> 设置loading: false状态 -> 完成');
                    return;
                }

                // 未配置月模板，不请求数据
                if (!response.data.year || !response.data.month) {
                    timeLog('初始化%c%s', 'color: #FAA809;', ' -> 未配置月模板，不请求数据');

                    timeLog('初始化%c%s', 'color: #FAA809;', ' -> 将数据设置为初始状态 -> 开始');
                    yield put({
                        type: modelType.INIT_STORE
                    });

                    yield put({
                        type: `${shareNamespace}/${modelType.E_SHARED_STATE}`,
                        payload: {
                            sharePeriod: null
                        }
                    });
                    timeLog('初始化%c%s', 'color: #FAA809;', ' -> 将数据设置为初始状态 -> 完成');

                    timeLog('初始化%c%s', 'color: #FAA809;', ' -> 设置loading：false状态 -> 开始');
                    yield put({
                        type: modelType.SET_LOADING,
                        payload: { tableLoading: false }
                    });
                    yield put({
                        type: modelType.E_LOAD_STEP
                    });
                    timeLog('初始化%c%s', 'color: #FAA809;', ' -> 设置loading: false状态 -> 完成');

                    yield put({
                        type: 'rejectTabModel/resetData'
                    });
                    return;
                }
                const { year, month } = response.data;

                timeLog('初始化%c%s', 'color: #FAA809;', ' -> 设置默认月份 -> 开始');
                // 设置默认月份
                yield put({
                    type: modelType.SET_PERIOD,
                    payload: `${year}-${(month < 10 ? '0' : '') + month}`
                });

                timeLog('初始化%c%s', 'color: #FAA809;', ' -> 设置默认月份 -> 完成');
            } else {
                timeLog('初始化%c%s', 'color: #FAA809;', ' -> 设置默认月份 -> 开始');
                // 设置默认月份
                yield put({
                    type: modelType.SET_PERIOD,
                    // payload: moment().from(new Date()).format('YYYY-MM')
                    payload: state.payload
                });
                timeLog('初始化%c%s', 'color: #FAA809;', ' -> 设置默认月份 -> 完成');
            }
            postData = yield* searchPostData(select, namespace);
            yield put({
                type: modelType.E_LOAD_STEP
            });
            yield put({
                type: 'rejectTabModel/initData',
                payload: { year: postData.year, month: postData.month, organizationCode: postData.organizationCode }
            });

            timeLog('初始化%c%s', 'color: #FAA809;', ' -> 请求操作按钮列表获取、查询表格表体数据 -> 开始');
            const [checkButtonsResponse, recordResponse] = yield all([
                // 操作按钮列表获取
                call(getCheckButtons, {
                    year: postData.year,
                    month: postData.month,
                    actionType: postData.actionType,
                    organizationCode: postData.organizationCode
                }),
                // 查询表格表体数据
                call(queryTableBodyData, postData)
            ]);
            timeLog('初始化%c%s', 'color: #FAA809;', ' -> 请求操作按钮列表获取、查询表格表体数据 -> 完成');

            let checkButtonList = [];
            if (isSuccess(checkButtonsResponse)) {
                checkButtonList = (checkButtonsResponse.data && checkButtonsResponse.data.tableToolButtonList) || [];
            } else {
                message.error(`${checkButtonsResponse.msg}`);
            }

            timeLog('初始化%c%s', 'color: #FAA809;', ' -> 设置按钮权限数据 -> 开始');
            yield put({
                type: modelType.SET_MULTI_STORE,
                payload: {
                    checkButtonList
                }
            });
            timeLog('初始化%c%s', 'color: #FAA809;', ' -> 设置按钮权限数据 -> 完成');

            timeLog('初始化%c%s', 'color: #FAA809;', ' -> 设置表格数据 -> 开始');
            if (isSuccess(recordResponse)) {
                yield put({
                    type: modelType.SET_PAGE_INFO,
                    payload: recordResponse
                });
            } else {
                yield put({
                    type: modelType.SET_PAGE_INFO,
                    payload: {
                        data: {}
                    }
                });
                message.error(`${recordResponse.msg}`);
            }
            timeLog('初始化%c%s', 'color: #FAA809;', ' -> 设置表格数据 -> 完成');

            timeLog('初始化%c%s', 'color: #FAA809;', ' -> 设置loading：false状态 -> 开始');
            yield put({
                type: modelType.SET_LOADING,
                payload: { tableLoading: false }
            });
            timeLog('初始化%c%s', 'color: #FAA809;', ' -> 设置loading：false状态 -> 完成');
            timeEnd('初始化%c%s');
        },

        *[modelType.E_SEARCH](s, { put, select }) {
            time('查询%c%s');
            timeLog('查询%c%s', 'color: #FAA809;', ' -> 设置查询条件 -> 开始');
            //  设置查询条件;
            if (s.payload) {
                yield put({
                    type: modelType.SET_SEARCH_CONDITION,
                    payload: s.payload
                });
            }
            timeLog('查询%c%s', 'color: #FAA809;', ' -> 设置查询条件 -> 完成');

            const postData = yield* searchPostData(select, namespace);

            if (!postData.year || !postData.month) {
                message.error('请选择薪资年月');
                return
            }

            timeLog('查询%c%s', 'color: #FAA809;', ' -> 获取表格数据 -> 开始');
            const tableData = yield* getTableData(select, namespace);
            timeLog('查询%c%s', 'color: #FAA809;', ' -> 获取表格数据 -> 结束');

            timeLog('查询%c%s', 'color: #FAA809;', ' -> 计算表格 -> 开始');
            const data = ComputeOverviewTable(tableData.historySource, {
                ...postData,
                ...s.payload
            });
            timeLog('查询%c%s', 'color: #FAA809;', ' -> 计算表格 -> 结束');

            timeLog('查询%c%s', 'color: #FAA809;', ' -> loading: true -> 开始');
            yield put({
                type: modelType.SET_LOADING,
                payload: { tableLoading: true }
            });
            timeLog('查询%c%s', 'color: #FAA809;', ' -> loading: true -> 结束');

            timeLog('查询%c%s', 'color: #FAA809;', ' -> 设置表格数据 -> 开始');
            yield put({
                type: modelType.SET_PAGE_INFO,
                payload: { data }
            });
            timeLog('查询%c%s', 'color: #FAA809;', ' -> 设置表格数据 -> 结束');

            timeLog('查询%c%s', 'color: #FAA809;', ' -> loading: false -> 开始');
            yield put({
                type: modelType.SET_LOADING,
                payload: { tableLoading: false }
            });
            timeLog('查询%c%s', 'color: #FAA809;', ' -> loading: false -> 结束');
            timeEnd('查询%c%s');

            // yield put({
            //     type: modelType.SET_LOADING,
            //     payload: { tableLoading: true }
            // });

            // const [response] = yield all([call(queryTableBodyData, postData)]);

            // if (isSuccess(response)) {
            //     yield put({
            //         type: modelType.SET_PAGE_INFO,
            //         payload: response
            //     });
            // } else {
            //     message.error(`请求表身数据失败：${response.msg}`);
            // }

            // yield put({
            //     type: modelType.SET_LOADING,
            //     payload: { tableLoading: false }
            // });
        },
        // 重置
        *[modelType.E_RESET](state, { put }) {
            yield put({
                type: modelType.RESET_STORE,
                payload: state.payload
            });
        },
        *[modelType.E_SEARCH_CONDITION](state, { put }) {
            yield put({
                type: modelType.SET_SEARCH_CONDITION,
                payload: state.payload
            });
            state.callback()
        },
        // 更新数据
        *[modelType.E_UPDATE_DATA](s, { select, call, put }) {
            const postData = yield* searchPostData(select, namespace);
            const response = yield call(updateData, {
                year: postData.year,
                month: postData.month,
                salaryPayrollIdList: _.map(s.payload, 'id'),
                organizationCode: postData.organizationCode
            });
            if (isSuccess(response)) {
                yield put({
                    type: modelType.E_INIT,
                    payload: `${postData.year}-${(postData.month < 10 ? '0' : '') + postData.month}`
                });
            } else {
                message.error(response.msg);
            }
        },
        /**
         * 所有按钮操作处理
         */
        *handleCheck(s, { put, select, call }) {
            if (!s.payload) {
                return;
            }
            const { fn, param } = s.payload;

            const postData = yield* searchPostData(select, namespace);
            const response = yield call(fn, {
                year: postData.year,
                month: postData.month,
                actionType: postData.actionType,
                organizationCode: postData.organizationCode,
                ...param
            });
            const { code, data } = response;
            if (code === 10000 && data && data.responseCode) {
                yield put({
                    type: 'articleWagesModel/openModal',
                    payload: {
                        articleWagesVisible: true,
                        articleWagesMsg: data.msg,
                        articleWagesPower: data.responseCode === 10000
                    }
                });
                return;
            }
            if (!isSuccess(response)) {
                message.error(`操作失败：${response?.msg}`);
                return;
            }
            message.success(response.msg);
            yield put({
                type: modelType.E_INIT,
                payload: `${postData.year}-${(postData.month < 10 ? '0' : '') + postData.month}`
            });
        },
        /**
         * 复审驳回
         */ *[modelType.E_REJECT_CHECK](s, { put }) {
            yield put({
                type: 'handleCheck',
                payload: {
                    fn: rejectCheck,
                    param: s.payload
                }
            });
        },

        /**
         * 复审通过
         */ *[modelType.E_PASS_CHECK](s, { put }) {
            yield put({
                type: 'handleCheck',
                payload: {
                    fn: passCheck
                }
            });
        },

        /**
         * 终审驳回
         */ *[modelType.E_FINAL_REJECT_CHECK](s, { put }) {
            yield put({
                type: 'handleCheck',
                payload: {
                    fn: finalRejectCheck,
                    param: s.payload
                }
            });
        },

        /**
         * 终审通过
         */ *[modelType.E_FINAL_PASS_CHECK](s, { put }) {
            yield put({
                type: 'handleCheck',
                payload: {
                    fn: finalPassCheck
                }
            });
        },
        /**
         * 为了让stepList加载
         */
        *[modelType.E_LOAD_STEP](s, { put, call }) {
            yield put({
                type: modelType.SET_MULTI_STORE,
                payload: { stepLoading: true }
            });
            // 延迟10ms
            yield call(delay, 10);
            yield put({
                type: modelType.SET_MULTI_STORE,
                payload: { stepLoading: false }
            });
        }
    }
});

export default overviewRecheckModel;
